package com.yj.springbootmybatis.rest;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yj.springbootmybatis.enums.RedisConstant;
import com.yj.springbootmybatis.pojo.Info;
import com.yj.springbootmybatis.pojo.User;
import com.yj.springbootmybatis.pojo.bo.UserBo;
import com.yj.springbootmybatis.pojo.vo.UserVo;
import com.yj.springbootmybatis.service.UserService;
import com.yj.springbootmybatis.util.CookieUtils;
import com.yj.springbootmybatis.util.MD5Utils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

@Controller
@RequestMapping("user")
@Api(tags = "用户模块")
@Slf4j
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    StringRedisTemplate redisTemplate;

    @GetMapping("index")
    public String getIndex(){
        return "login";
    }


    @GetMapping("userIsExist")
    @ResponseBody
    @ApiOperation(value = "判断用户名是否存在")
    public String userIsExist(@ApiParam(value = "用户名") @RequestParam String username){

        if (StringUtils.isBlank(username)){
            return "username is not empty!";
        }

        boolean b = userService.queryUsernameIsExist(username);

        if (b) {
            return "username is exist!";
        }
        return "username can use!";
    }


    @PostMapping("register")
    @ResponseBody
    @ApiOperation(value = "注册用户")
    public String register(@ApiParam(value = "用户实体")@RequestBody(required = true) UserBo userBo,HttpServletRequest request,HttpServletResponse response){
        String username = userBo.getUsername();
        String password = userBo.getPassword();
        String confirmPassword = userBo.getConfirmPassword();

        // 0.先验证用户名和密码是否为空
        if (StringUtils.isBlank(username)||StringUtils.isBlank(password)||StringUtils.isBlank(confirmPassword)){
            return "用户名和密码不能为空!";
        }
        // 1.再验证用户名是否存在
        if (userService.queryUsernameIsExist(username)){
            return "该用户名已存在！";
        }
        // 2.密码的长度不能小于6位
        if (password.length()<6 || confirmPassword.length()<6){
            return "密码长度不能小于6位！";
        }
        // 3.判断两次密码是否一致
        if(!StringUtils.equals(password,confirmPassword)){
            return "两次密码不一致";
        }
        // 4.注册
        User user = userService.createUser(userBo);

        // 5.实现用户redis 会话
        String userToken = UUID.randomUUID().toString().trim().replace("-","");
        redisTemplate.opsForValue().set(RedisConstant.REDIS_USER_TOKEN.key+":"+user.getId(),userToken);

        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);

        CookieUtils.addCookieInfo("token",userToken,request,response);

        return "注册成功！";

    }


    @ApiOperation(value = "用户登录",httpMethod = "POST")
    @PostMapping(value = "login")
    @ResponseBody
    public String login( UserBo userBo,HttpServletRequest request,HttpServletResponse response) throws JsonProcessingException {
        String username = userBo.getUsername();
        String password = userBo.getPassword();
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)){
            return "用户名和密码不能为空！";
        }

        User user = userService.queryForUserLogin(username, MD5Utils.md5Decode(password));
        if (null == user){
            return "用户名或密码不正确！";
        }
//        UserVo userVo = new UserVo();
//        BeanUtils.copyProperties(user,userVo);
        UserVo userVo = convertUserVo(user);
        log.info("login() => userVo:{}",userVo);

        ObjectMapper mapper = new ObjectMapper();
        String value = mapper.writeValueAsString(userVo);
        log.info("login() => value:{}",value);
        CookieUtils.addCookieInfo(userVo.getId(), value,request,response);
        CookieUtils.addCookieInfo("token", userVo.getUserToken(),request,response);

        return "登录成功";
    }

    private UserVo convertUserVo(User user){
        String userToken = UUID.randomUUID().toString().replace("-","").trim();
        redisTemplate.opsForValue().set(RedisConstant.REDIS_USER_TOKEN.key+":"+user.getId(),userToken);
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);
        return userVo;
    }

    @ApiOperation(value = "退出登录")
    @GetMapping("logout")
    @ResponseBody
    public String logout(@RequestParam String userId,HttpServletRequest req,HttpServletResponse resp){
        if (StringUtils.isBlank(userId)){
            return "当前用户暂未登录！";
        }
        redisTemplate.delete(RedisConstant.REDIS_USER_TOKEN.key+":"+userId);
        CookieUtils.clearCookieInfo(userId,req,resp);
        return "退出登录成功！";
    }
    @ApiOperation(value = "测试返回类型")
    @GetMapping("test")
    @ResponseBody
    public List test(){

        Info info1 = new Info();
        info1.setId(1);
        info1.setName("zs");
        info1.setPhone("123");

        Info info2 = new Info();
        info2.setId(2);
        info2.setName("ls");
        info2.setPhone("345");


        Info info3 = new Info();
        info3.setId(1);
        info3.setName("zs");
        info3.setPhone("123");

        Info info4 = new Info();
        info4.setId(3);
        info4.setName("yj");
        info4.setPhone("789");


        ArrayList<Info> list = new ArrayList<>();
        list.add(info1);
        list.add(info2);
        list.add(info3);
        list.add(info4);

        HashSet<Info> set = new HashSet<>(list);
        list.clear();
        list.addAll(set);
        return list;
    }



}
